/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.network;

import java.util.ArrayList;
import java.util.List;
import src.engine.PICAIUDice;
import src.engine.PICAIULuaScript;
import src.network.PICAIUBountyS;
import src.objects.PICAIUGameUnit;

/**
 *
 * @author Owner
 */
public class PICAIUAIMastermind {

  private PICAIURecruittedUnit parent;
  private PICAIUGame game;
  private ArrayList<PICAIULuaScript> scripts;
  private int restNum, restProb;
  private int moveToX, moveToY, moveToProb;
  private int runToX, runToY, runToProb;
  private PICAIURecruittedUnit toAttack;
  private int attackProb;
  private int goProneProb;
  public static int maxBounty = 3000 * 3000;
  private int elapsedAI = 0;

  public PICAIUAIMastermind(PICAIURecruittedUnit u, PICAIUGame g) {
    parent = u;
    game = g;
    if (u.type == 0) {
      scripts = PICAIUAIScripts.gunnerScripts;
    } else if (u.type == 1) {
      scripts = PICAIUAIScripts.tankScripts;
    } else if (u.type == 2) {
      scripts = PICAIUAIScripts.rocketScripts;
    }
  }

  public void update() {
    elapsedAI++;
    if (parent.status == PICAIURecruittedUnit.SHOOT) {
      parent.status = PICAIURecruittedUnit.NORMAL;
    }
    if (parent.status == PICAIURecruittedUnit.NORMAL) {
      for (PICAIULuaScript s : scripts) {
        s.runFunction("update", this);
      }
      act();
    }
  }

  public int getElapsedAI() {
    return elapsedAI;
  }

  public void act() {
    int total = restProb + moveToProb + runToProb + attackProb + goProneProb;
    int actual = PICAIUDice.roll(total);
    if (actual < restProb) {
      //rest
      parent.rest(restNum);
      //System.out.println("resting for "+restNum);
    } else if (actual < restProb + moveToProb) {
      //move

      //System.out.println("at "+parent.getX()+","+parent.getY());
      parent.move(moveToX, moveToY);
      //System.out.println("moving to "+moveToX+","+moveToY);
    } else if (actual < restProb + moveToProb + runToProb) {
      //move
      parent.run(runToX, runToY);
      //System.out.println("at "+parent.getX()+","+parent.getY());
      //System.out.println("running to "+moveToX+","+moveToY);
    } else if (actual < restProb + moveToProb + runToProb + attackProb) {
      //attack
      parent.attack(toAttack);
    } else {
      //goProne
    }

    //reset all
    restProb = moveToProb = runToProb = attackProb = goProneProb = 0;
  }

  public int getEnergy() {
    return parent.energy;
  }

  public int getMaxEnergy() {
    return parent.maxEnergy;
  }

  public int getBravery() {
    return parent.bravery;
  }

  public int getCuriousity() {
    return parent.curiousity;
  }

  public double getX() {
    return parent.getX();
  }

  public double getY() {
    return parent.getY();
  }

  public void rest(int r, int prob) {
    restNum = r;
    restProb = prob;
  }

  public void move(int x, int y, int prob) {
    moveToX = x;
    moveToY = y;
    moveToProb = prob;
  }

  public void run(int x, int y, int prob) {
    runToX = x;
    runToY = y;
    runToProb = prob;
  }

  public void attack(PICAIURecruittedUnit u, int prob) {
    toAttack = u;
    attackProb = prob;
  }

  public void goProne(int prob) {
    goProneProb = prob;
  }

  /*
   * returns all bounties within 3000 pixels away
   */
  public List getBounties() {
    //ArrayList<PICAIUBountyS> list = new ArrayList<PICAIUBountyS>();

    List<PICAIUBountyS> bounties = game.getBlueBounties();
    if (parent.isRedTeam()) {
      bounties = game.getRedBounties();
    }
    /*for (PICAIUBountyS b : bounties) {
      double x = b.getX() - parent.getX();
      x = x * x;
      double y = b.getY() - parent.getY();
      y = y * y;
      if (y + x < maxBounty) {
        list.add(b);
      }
    }*/
    return bounties;
  }

  public boolean isRedTeam() {
    return parent.isRedTeam();
  }

  /*
   * returns an arraylist of all the enemies in the unit's FOV.
   */
  public List getEnemies() {
    ArrayList<PICAIURecruittedUnit> list = new ArrayList<PICAIURecruittedUnit>();
    ArrayList<PICAIURecruittedUnit> units = game.getRedPersona().recruitted;
    if (parent.isRedTeam()) {
      units = game.getBluePersona().recruitted;
    }
    for (PICAIURecruittedUnit u : units) {
      double x = u.getX() - parent.getX();
      x = x * x;
      double y = u.getY() - parent.getY();
      y = y * y;
      if (u.status != PICAIURecruittedUnit.DEAD && y + x < (parent.vision / 2) * (parent.vision / 2)) {
        list.add(u);
      }
    }
    return list;
  }

  /*
   * returns an arraylist of comrades in the unit's FOV.
   */
  public List getComrades() {

    ArrayList<PICAIURecruittedUnit> list = new ArrayList<PICAIURecruittedUnit>();
    ArrayList<PICAIURecruittedUnit> units = game.getBluePersona().recruitted;
    if (parent.isRedTeam()) {
      units = game.getRedPersona().recruitted;
    }
    for (PICAIURecruittedUnit u : units) {
      double x = u.getX() - parent.getX();
      x = x * x;
      double y = u.getY() - parent.getY();
      y = y * y;
      if (u.status != PICAIURecruittedUnit.DEAD && y + x < (parent.vision / 2) * (parent.vision / 2)) {
        list.add(u);
      }
    }
    return list;
  }

  public int diceRoll(int sides) {
    return PICAIUDice.roll(sides);
  }

  public PICAIUUndiscoveredLocation getClosestUndiscoveredLocation(double x, double y) {
    if (parent.isRedTeam()) {
      return game.getClosestUndiscoveredLocationRed((int) x, (int) y);
    } else {
      return game.getClosestUndiscoveredLocationBlue((int) x, (int) y);
    }
  }

  public ArrayList<PICAIUUndiscoveredLocation> getUndiscoveredLocations() {
    if (parent.isRedTeam()) {
      return game.getUndiscoveredLocationsRed();
    } else {
      return game.getUndiscoveredLocationsBlue();
    }
  }

  public int getWorth(){
    return parent.worth;
  }
}
